﻿using BCCommon;
using BCCommon.Enums;
using BCData.Trading.Purchase.GoodsPurchaseCertificate;
using BCDto.Trading.Purchase.GoodsPurchaseCertificate;
using BCEntity.Trading.Purchase.GoodsPurchaseCertificate;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BCData.Trading.Purchase.GoodsPurchase;
using BCCommon.TradingEnums;
using BCDto.Sim.Admin.Admin;

namespace BCService.Trading.Purchase.GoodsPurchaseCertificate
{
    public class GoodsPurchaseCertificateService : IGoodsPurchaseCertificateService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IRedisService redisService;
        private readonly IGoodsPurchaseCertificateData goodsPurchaseCertificateData;
        private readonly IGoodsPurchaseData goodsPurchaseData;
        private readonly string key = string.Format("{0}", EntityNameConst.GoodsPurchaseCertificateEntity);

        public GoodsPurchaseCertificateService(IDatabaseContext databaseContext,
            IRedisService redisService,
            IGoodsPurchaseCertificateData goodsPurchaseCertificateData,
            IGoodsPurchaseData goodsPurchaseData)
        {
            this.databaseContext = databaseContext;
            this.redisService = redisService;
            this.goodsPurchaseCertificateData = goodsPurchaseCertificateData;
            this.goodsPurchaseData = goodsPurchaseData;
        }

        #region 检查商品采购单记账凭证是否存在
        public bool Exists(long goodsPurchaseCertificateId)
        {
            return this.goodsPurchaseCertificateData.Exists(goodsPurchaseCertificateId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加商品采购单记账凭证
        public GoodsPurchaseCertificateDto Add(GoodsPurchaseCertificateRequestDto requestDto,AdminDto adminDto)
        {
            if (this.goodsPurchaseCertificateData.Exists(requestDto.CertificateNo).Result)
            {
                throw new ArgumentException("此凭证编号已存在!");
            }
            if (!this.goodsPurchaseData.Exists(requestDto.GoodsPurchaseId).Result)
            {
                throw new ArgumentException("此采购单信息不存在!");
            }
            var purchaseEntity = this.goodsPurchaseData.GetEntity(requestDto.GoodsPurchaseId).Result;

            var entity = requestDto.As<GoodsPurchaseCertificateEntity>();
            entity.CreateAdminName = adminDto.FullName;
            entity.CreateAdminId = adminDto.AdminId;
            entity.GoodsPurchaseNo = purchaseEntity.GoodsPurchaseNo;
            if (entity.PaidType == PurchasePaidType.Deposite)
            {
                purchaseEntity.DepositePaymentCertificateNo = entity.CertificateNo;
                databaseContext.BeginTransaction();
                var result = this.goodsPurchaseCertificateData.Add(entity).GetAwaiter().GetResult();
                var purchaseResult = this.goodsPurchaseData.UpdateDepositeCertificate(purchaseEntity).Result;
                databaseContext.Commit();
                return result.As<GoodsPurchaseCertificateDto>();
            }
            else
            {
                purchaseEntity.LastPaymentCertificateNo = entity.CertificateNo;
                databaseContext.BeginTransaction();
                var result = this.goodsPurchaseCertificateData.Add(entity).GetAwaiter().GetResult();
                var purchaseResult = this.goodsPurchaseData.UpdateLastPaymentCertificate(purchaseEntity).Result;
                databaseContext.Commit();
                return result.As<GoodsPurchaseCertificateDto>();
            }
        
        }
        #endregion

        #region 修改商品采购单记账凭证
        public GoodsPurchaseCertificateDto Update(GoodsPurchaseCertificatePutDto putDto,AdminDto adminDto)
        {
            if (!this.Exists(putDto.GoodsPurchaseCertificateId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            if (!this.goodsPurchaseData.Exists(putDto.GoodsPurchaseId).Result)
            {
                throw new ArgumentException("此采购单信息不存在!");
            }
            var oldEntity = this.Get(putDto.GoodsPurchaseCertificateId);
            if (this.goodsPurchaseCertificateData.Exists(putDto.CertificateNo).Result)
            {
                if (oldEntity.CertificateNo != putDto.CertificateNo)
                {
                    throw new ArgumentException("此凭证编号已存在!");
                }
            }

            var purchaseEntity = this.goodsPurchaseData.GetEntity(putDto.GoodsPurchaseId).Result;
            var entity = putDto.As<GoodsPurchaseCertificateEntity>();
            entity.CreateAdminName = adminDto.FullName;
            entity.CreateAdminId = adminDto.AdminId;
            entity.GoodsPurchaseNo = purchaseEntity.GoodsPurchaseNo;
            if (entity.PaidType == PurchasePaidType.Deposite)
            {
                purchaseEntity.DepositePaymentCertificateNo = entity.CertificateNo;
                databaseContext.BeginTransaction();
                var result = this.goodsPurchaseCertificateData.Update(entity).GetAwaiter().GetResult();
                var purchaseResult = this.goodsPurchaseData.UpdateDepositeCertificate(purchaseEntity).Result;
                databaseContext.Commit();
                string cacheKey = this.redisService.GetKey(key, entity.GoodsPurchaseCertificateId);
                this.redisService.DeleteAsync(cacheKey);
                return result.As<GoodsPurchaseCertificateDto>();
            }
            else
            {
                purchaseEntity.LastPaymentCertificateNo = entity.CertificateNo;
                databaseContext.BeginTransaction();
                var result = this.goodsPurchaseCertificateData.Update(entity).GetAwaiter().GetResult();
                var purchaseResult = this.goodsPurchaseData.UpdateLastPaymentCertificate(purchaseEntity).Result;
                databaseContext.Commit();
                string cacheKey = this.redisService.GetKey(key, entity.GoodsPurchaseCertificateId);
                this.redisService.DeleteAsync(cacheKey);
                return result.As<GoodsPurchaseCertificateDto>();
            }
           
        }
        #endregion

        #region 删除商品采购单记账凭证
        public bool Delete(long goodsPurchaseCertificateId)
        {
            if (!this.Exists(goodsPurchaseCertificateId))
            {
                throw new ArgumentException("此记录不存在!");
            }

            var result = this.goodsPurchaseCertificateData.Delete(goodsPurchaseCertificateId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseCertificateId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 获取商品采购单记账凭证
        public GoodsPurchaseCertificateDto Get(long goodsPurchaseCertificateId)
        {
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseCertificateId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.goodsPurchaseCertificateData.GetEntity(goodsPurchaseCertificateId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromMinutes(30));
            return result.As<GoodsPurchaseCertificateDto>();
        }
        #endregion

        #region 获取商品采购单记账凭证列表
        public IEnumerable<GoodsPurchaseCertificateDto> GetList(long goodsPurchaseId)
        {
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseId);
            var result = this.redisService.TryGet(key, () =>
            {
                return this.goodsPurchaseCertificateData.GetList(goodsPurchaseId).GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(30));
            return result.As<IEnumerable<GoodsPurchaseCertificateDto>>();
        }
        #endregion

        #region 获取商品采购单记账凭证分页
        public PageableList<GoodsPurchaseCertificateDto> Query(long? goodsPurchaseId, string certificateNo, DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseId, certificateNo, start, end, sortName, ascending, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.goodsPurchaseCertificateData.Query(goodsPurchaseId, certificateNo, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<GoodsPurchaseCertificateDto>
                {
                    Count = data.Item2,
                    Items = data.Item1.As<IEnumerable<GoodsPurchaseCertificateDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now
                };
            }, TimeSpan.FromMinutes(30));

            return result;
        }
        #endregion
    }
}